﻿
using DataWorks_Sqlite.MappingClass;
using DataWorks_Tools.BasicMethods;
using DataWorks_Tools.HalfHourCalSave.Common.Basic;
using DataWorks_Tools.MappModals.CalInputModals;
using DataWorks_Tools.MappModals.CalSaveModals;

using RainFlowandDamageTool.ComputingProcess;

using Yitter.IdGenerator;
using static DataWorks_Tools.BasicMethods.ReadfromCSV;

namespace DataWorks_Tools.HalfHourCalSave.Common.DataImport
{
    public static class Tools_SpdFromtoImport
    {
        public static async Task<List<calsave_spdfromto_split>> GetSpdFromtoPrecisionAsync(CSVImport csvimport, dw_props_admin admin, HalfHourCalInputModel props)
        {
            List<calsave_spdfromto_split> result = new();
            if (props.importspdfromto == 1)
            {
                var spdlist = await ReadfromCSV.GetSpecifiedColumnDataAsync(csvimport, props.chantitle_spd);
                var brakelist = await ReadfromCSV.GetSpecifiedColumnDataAsync(csvimport, props.chantitle_brake);
                var throttlelist = await ReadfromCSV.GetSpecifiedColumnDataAsync(csvimport, props.chantitle_throttle);
                if(spdlist != null && brakelist != null && throttlelist != null)
                {
                    //这里指源数据每downsamplerate个取一点，这里是每32个点取1个，相当于16hz
                    var downsamplerate = admin.samplerate / admin.spdfromtoresamplerate;
                    //先降采样，降低到10hz，好处理
                    var downspdlist = spdlist.DownSample(downsamplerate);
                    var downbrakelist = brakelist.DownSample(downsamplerate);
                    var downthrottlelist = throttlelist.DownSample(downsamplerate);
                    if(downspdlist != null && downbrakelist != null && downthrottlelist != null)
                    {
                        //先置零再查找峰谷值序号，再获得峰谷值
                        var zerospd = downspdlist.DoSpdZero();
                        var index = zerospd.FindpeaksIndex();
                        var peakvalley = zerospd.GetDataValues(index);
                        var peakvalleystruct = peakvalley.GetPeakValleyFromtoList(index);
                        var peakvalleyresult = peakvalleystruct.CombinePeakValleyFromtoStru(0);
                        peakvalleyresult.EditStruforLastZero(zerospd);
                        int d = 1;//用于给filename区分每个fromto
                        for (int i = 0; i < peakvalleyresult.Count; i++)
                        {
                            var spdfrombin = peakvalleyresult[i].spdfrom.GetSpdBin();
                            var spdtobin = peakvalleyresult[i].spdto.GetSpdBin();
                            var realtime = (peakvalleyresult[i].toindex - peakvalleyresult[i].fromindex) * 1.0 / admin.spdfromtoresamplerate;
                            //var lastingtime = (peakvalleyresult[i].toindex-peakvalleyresult[i].fromindex) * (downsamplerate);
                            var throttlepos = downthrottlelist.GetMaxValue(peakvalleyresult[i].fromindex, peakvalleyresult[i].toindex);
                            var brakepos = downbrakelist.GetMaxValue(peakvalleyresult[i].fromindex, peakvalleyresult[i].toindex);
                            var calaccx = (peakvalleyresult[i].spdfrom - peakvalleyresult[i].spdto) / 3.6 / 9.8 / realtime;
                            var level = calaccx.GetAccLevel();
                            var conditiontype = SpdFromtoMethods.GetConditionType(peakvalleyresult[i].spdfrom < peakvalleyresult[i].spdto, throttlepos, brakepos);
                            var createTime = Convert.ToDateTime(csvimport.datetime);
                            for (int j = 1; j < csvimport.columncount; j++)
                            {
                                calsave_spdfromto_split row = new();
                                row.key = YitIdHelper.NextId();
                                row.createTime = createTime;
                                row.vehicle = props?.vehicle;
                                row.project = props?.project;
                                row.filename = csvimport.name + "-C" + d;//区分每个fromto的名称
                                row.datadate = Convert.ToDateTime(csvimport.datetimesecond);
                                row.subdirectory = csvimport.subdirectory;
                                row.spdfrom = peakvalleyresult[i].spdfrom;
                                row.spdfrombin = spdfrombin;
                                row.spdto = peakvalleyresult[i].spdto;
                                row.spdtobin = spdtobin;
                                row.lastingtime = realtime;
                                row.brakepos = brakepos;
                                row.throttlepos = throttlepos;
                                row.calaccx = calaccx;
                                row.conditiontype = conditiontype;
                                row.level = level;
                                row.chantitle = csvimport.headers[j];
                                //先把每个数据集降采样然后获取每个fromto区间的数据集
                                var data = csvimport.lists[j].DownSample(downsamplerate).GetDataValues(peakvalleyresult[i].fromindex, peakvalleyresult[i].toindex);
                                row.smax = data.Max();
                                row.smin = data.Min();
                                row.smean = data.Average();
                                row.srange = Math.Abs(row.smax - row.smin);
                                double variance = data.Sum(x => Math.Pow(x - row.smean, 2)) / (data.Count - 1);
                                row.std = Math.Sqrt(variance);
                                row.damagek3 = data.GetAccumDamagefromList(3, 3, admin.binnumber);//bin的数量，目前是100
                                row.damagek5 = data.GetAccumDamagefromList(5, 5, admin.binnumber);
                                double sumOfSquares = data.Sum(x => x * x);
                                double meanSquare = sumOfSquares / (data.Count - 1);
                                row.srms = Math.Sqrt(meanSquare);
                                if (j == 1 || j == 2)
                                {
                                    row.smax = data[0];
                                    row.smin = data[0];
                                    row.smean = data[0];
                                    row.srange = data[0];
                                    row.std = data[0];
                                    row.damagek3 = 0;
                                    row.damagek5 = 0;
                                    row.srms = data[0];
                                }
                                result.Add(row);
                            }
                            d++;
                        }
                        
                    }
                }
            }
            return result;
        }


        public static async Task<List<calsave_spdfromto_split>> GetSpdFromtoAsync(CSVImport csvimport, dw_props_admin admin, HalfHourCalInputModel props)
        {
            List<calsave_spdfromto_split> result = new();
            if (props.importspdfromto == 1)
            {
                var spdlist = await ReadfromCSV.GetSpecifiedColumnDataAsync(csvimport, props.chantitle_spd);
                var brakelist = await ReadfromCSV.GetSpecifiedColumnDataAsync(csvimport, props.chantitle_brake);
                var throttlelist = await ReadfromCSV.GetSpecifiedColumnDataAsync(csvimport, props.chantitle_throttle);
                if (spdlist != null && brakelist != null && throttlelist != null)
                {
                    //这里指源数据每downsamplerate个取一点，这里是每51个点取1个，相当于10hz
                    var downsamplerate = admin.samplerate / admin.spdfromtoresamplerate;//downsamplerate==51
                    //先降采样，降低到10hz，好处理
                    var downspdlist = spdlist.DownSample(downsamplerate);
                    var downbrakelist = brakelist.DownSample(downsamplerate);
                    var downthrottlelist = throttlelist.DownSample(downsamplerate);
                    if (downspdlist != null && downbrakelist != null && downthrottlelist != null)
                    {
                        //查找峰谷值
                        var index = downspdlist.FindpeaksIndex();
                        if (index?.Count > 1)
                        {
                            int d = 1;//用于给filename区分每个fromto
                            for (int i = 0; i < index.Count - 1; i++)
                            {
                                var spdfrom = downspdlist[index[i]];
                                var spdfrombin = spdfrom.GetSpdBin();
                                var spdto = downspdlist[index[i + 1]];
                                var spdtobin = spdto.GetSpdBin();
                                //去掉那些小变化的速度的区间
                                if (Math.Abs(spdfrom - spdto) > 5)
                                {
                                    var lastingtime = (index[i + 1] - index[i]) * (downsamplerate);//换算成512hz的点数了
                                    var brakepos = downbrakelist.GetMaxValue(index[i], index[i + 1]);
                                    var throttlepos = downthrottlelist.GetMaxValue(index[i], index[i + 1]);
                                    var calaccx = (spdfrom - spdto) / 3.6 / 9.8 / (lastingtime * 1.0 / admin.samplerate);//(lastingtime*1.0 / admin.samplerate)乘以1.0才能转换成double
                                    var level = calaccx.GetAccLevel();
                                    var conditiontype = SpdFromtoMethods.GetConditionType(spdfrom < spdto, throttlepos, brakepos);
                                    var createTime = Convert.ToDateTime(csvimport.datetime);
                                    for (int j = 1; j < csvimport.columncount; j++)
                                    {
                                        calsave_spdfromto_split row = new();
                                        row.key = YitIdHelper.NextId();
                                        row.createTime = createTime;
                                        row.vehicle = props?.vehicle;
                                        row.project = props?.project;
                                        row.filename = csvimport.name + "-spdfromto-" + d;//区分每个fromto的名称
                                        row.datadate = Convert.ToDateTime(csvimport.datetimesecond);
                                        row.subdirectory = csvimport.subdirectory;
                                        row.spdfrom = spdfrom;
                                        row.spdfrombin = spdfrombin;
                                        row.spdto = spdto;
                                        row.spdtobin = spdtobin;
                                        row.lastingtime = lastingtime;
                                        row.brakepos = brakepos;
                                        row.throttlepos = throttlepos;
                                        row.calaccx = calaccx;
                                        row.conditiontype = conditiontype;
                                        row.level = level;
                                        row.chantitle = csvimport.headers[j];
                                        //先把每个数据集降采样然后获取每个fromto区间的数据集
                                        var data = csvimport.lists[j].DownSample(downsamplerate).GetDataValues(index[i], index[i + 1]);
                                        row.smax = data.Max();
                                        row.smin = data.Min();
                                        row.smean = data.Average();
                                        row.srange = Math.Abs(row.smax - row.smin);
                                        double variance = data.Sum(x => Math.Pow(x - row.smean, 2)) / (data.Count - 1);
                                        row.std = Math.Sqrt(variance);
                                        row.damagek3 = data.GetAccumDamagefromList(3, 3, admin.binnumber);//bin的数量，目前是100
                                        row.damagek5 = data.GetAccumDamagefromList(5, 5, admin.binnumber);
                                        double sumOfSquares = data.Sum(x => x * x);
                                        double meanSquare = sumOfSquares / (data.Count - 1);
                                        row.srms = Math.Sqrt(meanSquare);
                                        if (j == 1 || j == 2)
                                        {
                                            row.smax = data[0];
                                            row.smin = data[0];
                                            row.smean = data[0];
                                            row.srange = data[0];
                                            row.std = data[0];
                                            row.damagek3 = 0;
                                            row.damagek5 = 0;
                                            row.srms = data[0];
                                        }
                                        result.Add(row);
                                    }
                                    d++;
                                }
                            }
                        }
                    }
                }
            }
            return result;
        }
    }
}
